<?php
/**
 * Copyright (c) 2020
 * 摘    要：
 * 作    者：san
 * 修改日期：2020.03.30
 */

namespace App\Middleware;

use App\Model\Role;
use App\Model\User;
use App\Model\WorkSpaceUser;
use App\Service\UserService;
use Donjan\Permission\PermissionRegistrar;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Context;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\Contract\ConfigInterface;

class PermissionMiddleware implements MiddlewareInterface
{
    /**
     * @Inject
     * @var \Hyperf\HttpServer\Contract\ResponseInterface
     */
    protected $response;

    /**
     * @Inject()
     * @var  UserService
     */
    protected $service;

    /**
     * @Inject
     * @var ConfigInterface
     */
    protected $config;

    const SEGMENT_NUM = 3;

    /**
     * @param ServerRequestInterface $request
     * @param RequestHandlerInterface $handler
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        try {
            $dispatcher = $request->getAttribute('Hyperf\HttpServer\Router\Dispatched');

            $callback = $dispatcher->handler->callback;
            if (!is_array($callback) || count($callback) != self::SEGMENT_NUM) {
                throw new \ErrorException("路由配置错误，请参考示例");
            }

            $alias = $dispatcher->handler->callback[2];

            $user = Context::get('user');
            if ($user->user_id === User::ADMIN_UID) {
                return $handler->handle($request);
            } else {
                $access = $this->service->_getUserPermissions($user);
                if (in_array($alias, $access)) {
                    return $handler->handle($request);
                } else {
                    throw new \ErrorException("当前用户没有{$alias}权限");
                }
            }
        } catch (\Exception $exception) {
            return $this->response->json(['code' => 500, 'status' => false, 'message' => $exception->getMessage()]);
        }
    }
}
